package com.yc.cloud.admin.service.impl;

import com.yc.cloud.common.orm.CommonPage;
import com.yc.cloud.common.oss.service.OssFileService;
import com.yc.cloud.common.basic.dto.BasePageReqDTO;
import com.yc.cloud.admin.dto.request.AlgAlgorithmCreateReqDTO;
import com.yc.cloud.admin.dto.request.AlgAlgorithmUpdateReqDTO;
import com.yc.cloud.admin.vo.AlgAlgorithmVo;
import com.yc.cloud.entity.AlgAlgorithm;
import com.yc.cloud.mapper.AlgAlgorithmMapper;
import com.yc.cloud.admin.service.AlgAlgorithmService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yc.cloud.admin.dto.request.AlgAlgorithmBindModelReqDTO;
import com.yc.cloud.admin.service.AlgModelService;
import com.yc.cloud.common.basic.dto.BasePageReqDTO;
import com.yc.cloud.common.basic.exception.Asserts;
import com.yc.cloud.entity.AlgModel;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.hutool.core.util.StrUtil;
import java.util.Objects;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 算法信息表 服务实现类
 * </p>
 *
 * @author kinggu
 * @since 2025-07-11
 */
@Service
public class AlgAlgorithmServiceImpl extends ServiceImpl<AlgAlgorithmMapper, AlgAlgorithm> implements AlgAlgorithmService {

    @Resource
    private AlgModelService algModelService;

    @Resource
    private OssFileService ossFileService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean create(AlgAlgorithmCreateReqDTO createReqDTO) {
        AlgAlgorithm entity = new AlgAlgorithm();
        BeanUtils.copyProperties(createReqDTO, entity);
        return save(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(AlgAlgorithmUpdateReqDTO updateReqDTO) {
        AlgAlgorithm entity = new AlgAlgorithm();
        BeanUtils.copyProperties(updateReqDTO, entity);
        return updateById(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean bindModel(Long algorithmId, AlgAlgorithmBindModelReqDTO bindModelReqDTO) {
        // 1. 验证算法是否存在
        AlgAlgorithm algorithm = getById(algorithmId);
        if (algorithm == null) {
            Asserts.fail("算法不存在");
        }

        // 2. 验证待绑定的模型是否存在
        Long modelIdToBind = bindModelReqDTO.getModelId();
        AlgModel modelToBind = algModelService.getById(modelIdToBind);
        if (modelToBind == null) {
            Asserts.fail("待绑定的模型不存在");
        }

        // 3. 解绑当前算法下的其他模型
        QueryWrapper<AlgModel> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(AlgModel.AlgorithmId, algorithmId);
        List<AlgModel> currentlyBoundModels = algModelService.list(queryWrapper);

        for (AlgModel boundModel : currentlyBoundModels) {
            if (!boundModel.getId().equals(modelIdToBind)) {
                boundModel.setAlgorithmId(null);
                algModelService.updateById(boundModel);
            }
        }

        // 4. 绑定新模型
        if (!algorithmId.equals(modelToBind.getAlgorithmId())) {
            modelToBind.setAlgorithmId(algorithmId);
            algModelService.updateById(modelToBind);
        }

        return true;
    }

    @Override
    public CommonPage<AlgAlgorithmVo> list(BasePageReqDTO pageReqDTO) {
        QueryWrapper<AlgAlgorithm> queryWrapper = new QueryWrapper<>();

        // 排序
        if (StrUtil.isNotEmpty(pageReqDTO.getSortBy())) {
            // 注意：pageReqDTO.getSortBy() 需要是数据库中的列名（驼峰转下划线），请注意防护SQL注入
            if (Objects.equals(BasePageReqDTO.ORDER_DESC, pageReqDTO.getOrder())) {
                queryWrapper.orderByDesc(StrUtil.toUnderlineCase(pageReqDTO.getSortBy()));
            } else {
                queryWrapper.orderByAsc(StrUtil.toUnderlineCase(pageReqDTO.getSortBy()));
            }
        }

        // 关键字模糊查询
        if (StrUtil.isNotEmpty(pageReqDTO.getKeyword())) {
            // TODO: 请根据业务需求，修改需要模糊查询的字段，以下为示例
            // queryWrapper.and(wrapper -> wrapper.like("name", pageReqDTO.getKeyword())
            //                                   .or()
            //                                   .like("description", pageReqDTO.getKeyword()));
        }
        
        // 根据 page 参数决定是否分页
        if (Boolean.TRUE.equals(pageReqDTO.getPage())) {
            Page<AlgAlgorithm> page = new Page<>(pageReqDTO.getPageNum(), pageReqDTO.getPageSize());
            Page<AlgAlgorithm> dbPage = baseMapper.selectPage(page, queryWrapper);
            return CommonPage.restPage(dbPage.convert(this::convertToVo));
        } else {
            List<AlgAlgorithm> allRecords = baseMapper.selectList(queryWrapper);
            CommonPage<AlgAlgorithmVo> result = new CommonPage<>();
            result.setList(convertToVoList(allRecords));
            result.setTotal((long) allRecords.size());
            result.setPageNum(1);
            result.setPageSize(allRecords.size());
            result.setTotalPage(1);
            return result;
        }
    }

    @Override
    public AlgAlgorithmVo getVOById(Long id) {
        AlgAlgorithm entity = getById(id);
        return convertToVo(entity);
    }

    @Override
    public List<AlgAlgorithmVo> convertToVoList(List<AlgAlgorithm> entityList) {
        if (entityList == null) {
            return null;
        }
        return entityList.stream()
                .map(this::convertToVo)
                .collect(Collectors.toList());
    }

    private AlgAlgorithmVo convertToVo(AlgAlgorithm entity) {
        if (entity == null) {
            return null;
        }
        AlgAlgorithmVo vo = new AlgAlgorithmVo();
        BeanUtils.copyProperties(entity, vo);
        if(StrUtil.isNotEmpty(entity.getIcon())){
            vo.setIconUrl(ossFileService.getOssFileUrl(entity.getIcon()));
        }
        return vo;
    }

    @Override
    public AlgAlgorithm get(Long id) {
        return getById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(Long id) {
        return removeById(id);
    }
} 